#include "../../include/loginAuth.h"

int login_auth(const char* userName, const char* password, char *buf, int buf_len){
    bzero(buf, buf_len);
    //getspnam_r准备工作
    //int getspnam_r(const char *name, struct spwd *spbuf, 
    //                  char *buf, size_t buflen, struct spwd **spbuf)
    struct spwd spbuf;
    struct spwd *spbufp;
    //推荐 spbuffer放在堆上 更健壮安全 避免耗尽线程的栈空间导致服务器崩溃
    //char spbuffer[4096] = {0}; //存放spwd结构体中的字符串
    int spbuffer_len = 4096;
    char *spbuffer = (char *)calloc(spbuffer_len, sizeof(char));
    
    //调用getspnam_r获得shadow信息
    getspnam_r(userName, &spbuf, spbuffer, spbuffer_len, &spbufp);
    
    //检查用户是否存在
    if(spbufp == NULL){
        sprintf(buf, "用户不存在.\n");
        free(spbuffer);
        return -1;
    }

    //crypt_r准备工作
    struct crypt_data data;
    data.initialized = 0; //需初始化

    //对输入密码进行加密 对比
    //根据sp_pwdp中有盐值+哈希值 crypt_r 会自动截断->按盐值加密
    char *crypt_pass = crypt_r(password, spbufp->sp_pwdp, &data); 
    
    //对比
    if(strcmp(crypt_pass, spbufp->sp_pwdp)){
        //代表哈希不同 密码错误
        free(spbuffer);
        sprintf(buf, "密码错误.\n");
        return -1;
    }
    //认证成功
    sprintf(buf, "认证成功.\n");
    free(spbuffer);
    return 0;
}

 
